using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using CoachingOrganizer.Toolkit.Patterns;
using System.Collections.Specialized;

namespace CoachingOrganizer.iOS.Decorators
{
    public class SimpleTableDataSourceDecorator<TSubController, TSubModel> : DisposableObject
        where TSubController : UIViewController
        where TSubModel : class
    {
        private readonly string _cellIdentifer;
        private readonly UITableView _tableView;
        private readonly UIViewController _controller;
        private readonly Func<NSIndexPath, TSubModel> _getSubModelDelegate;
        private readonly Func<TSubModel, TSubController> _getSubControllerDelegate;
        private readonly Lazy<NSString> _platformCellIdentifer;

        public SimpleTableDataSourceDecorator(string cellIdentifer, UITableView tableView, UIViewController controller, Func<NSIndexPath, TSubModel> getSubModelDelegate, Func<TSubModel, TSubController> getSubControllerDelegate)
        {
            _cellIdentifer = cellIdentifer;
            _tableView = tableView;
            _controller = controller;
            _getSubModelDelegate = getSubModelDelegate;
            _getSubControllerDelegate = getSubControllerDelegate;
            _platformCellIdentifer = new Lazy<NSString>(() => new NSString(cellIdentifer));
        }

        public UITableViewCell GetCell(NSIndexPath indexPath)
        {
            UITableViewCell cell = _tableView.DequeueReusableCell(_platformCellIdentifer.Value, indexPath);
            if (cell.ContentView.Subviews.Length == 0)
            {
                TSubModel itemModel = _getSubModelDelegate(indexPath);
                if (itemModel == null)
                    return cell;
                TSubController cellController = _getSubControllerDelegate(itemModel);
                _controller.AddChildViewController(cellController);
                cell.ContentView.Add(cellController.View);
            }
            return cell;
        }

        public void ProceedCollectionReplaced()
        {
            _tableView.BeginInvokeOnMainThread(() => _tableView.ReloadData());
        }

        public void ProceedCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            _tableView.BeginInvokeOnMainThread(() => _tableView.ReloadData());
        }
    }
}